package com.dreamlin.basepro.exceptions;

import com.dreamlin.basepro.base.viewmodel.BaseViewModel;
import com.dreamlin.basepro.base.viewmodel.LoadingModel;

import org.json.JSONException;

import java.net.SocketException;
import java.net.SocketTimeoutException;

import io.reactivex.Observable;
import io.reactivex.ObservableTransformer;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;


public class RxHelper {

    public static <T> ObservableTransformer<T, T> applySchedulers(BaseViewModel viewModel) {
        return upstream -> upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public static <T> ObservableTransformer<T, T> applySchedulersWithLoading(BaseViewModel viewModel) {
        return upstream -> upstream.subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> viewModel.setLoading(LoadingModel.getShowInstance()))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doFinally(() -> viewModel.setLoading(LoadingModel.getHideInstance()));
    }

    public static <T> GlobalErrorTransform<SuperBean<T>> withGlobalError(BaseViewModel viewModel) {
        return new GlobalErrorTransform<>(
                next -> {
                    //TODO:something
                    if (next.code == 200 || next.code == 0)
                        return Observable.just(next);
                    else
                        return Observable.error(new UnityException(next.code, next.message));
                },
                //onError
                error -> {
                    //TODO:something
                    return Observable.error(error);
                },
                //doRetry
                throwable -> {
                    if (throwable instanceof SocketTimeoutException) {
                        return new RetryConfig(1, 3000,
                                () -> Single.create(emitter -> {
                                    emitter.onSuccess(true);
                                }));
                    }
                    return new RetryConfig();
                },
                //doOnError
                throwable -> {
                    if (throwable instanceof JSONException) {
                        viewModel.setError("数据解析异常");
                    } else if (throwable instanceof SocketException) {
                        viewModel.setError("请求超时");
                    } else if (throwable instanceof UnityException) {
                        //case ....
                        viewModel.setError(throwable.getMessage());
                    }
                }
        );
    }

}
